iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
Software Development

小青蛇變大蟒蛇——進階Python學起來!系列 第 13

Python 與浮點數(float):什麼是 banker rounding?

  • 分享至 

  • xImage
  •  

float rounding, 浮點數的數值簡化

昨天討論了在 Python 中的三種浮點數簡化:truncate, flooring, ceiling。今天我們來學習最後一種有趣的簡化方法:round

help(round)
Help on built-in function round in module builtins:

round(number, ndigits=None)
    Round a number to a given precision in decimal digits.
    
    The return value is an integer if ndigits is omitted or None.  Otherwise
    the return value has the same type as the number.  ndigits may be negative.

看上述說明可以得知,round 會把數值簡化到小數點後 ndigits 位,預設是第0位,也就是回傳一個整數:

round(1.234)
1

你也可以指定 round 到小數點後幾位數:

round(1.234, 2)
1.23

小數點後幾位數可以是“負“的,代表 round 到小數點前幾位數:

round(123.45, -1)
120.0

round 的意思是根據你指定要簡化到的位數,回傳最靠近的數字:

round(100.1), round(100.7)
(100, 101)

不過,如果數字剛好在中間怎麼辦呢?我們從小學到的規則就叫:四捨五入。

Python應該也是如此,對吧?

round(1.35, 1)
1.4

看起來是四捨五入,為了保險我們再測試一個數字好了:

round(1.25, 1)
1.2

怪事發生了!round(1.25, 1) 答案竟然是 1.2 ?
為什麼?

banker rounding

其實 Python 使用的並非四捨五入,而是一種叫做 banker rounding 的簡化規則,什麼是 banker rounding?

根據 IEEE standard 的解釋:

Rounds to the nearest value, with ties rounded to the nearest value with an
even least significant digit.

意思是,若數值在中間,簡化到最小有效位數的偶數

這是什麼意思?檢查下面的範例:

round(1.35, 1), round(1.25, 1)
(1.4, 1.2)

第一個數字 1.35 在 1.3 和 1.4 的正中間,round 到小數點後第一位,選擇偶數的 1.4。

第一個數字 1.25 在 1.2 和 1.3 的正中間,round 到小數點後第一位,選擇偶數的 1.2。

為什麼要用這種 banker rounding 演算法?

顧名思義,這是銀行行員會想用的算法,為什麼呢?因為單純的四捨五入,可能會讓銀行損失慘重。

假設有一個人存了四筆錢進銀行:1.5元, 2.5元, 3.5元, 4.5元,四筆錢四捨五入後加起來平均:

(2 + 3 + 4 + 5) / 4 = 14 / 4 = 3.5

跟真正的值 (1.5 + 2.5 + 3.5 + 4.5) / 4 = 12 / 4 = 3 比起來多了 0.5 元。

我們可以發現四捨五入是一種不斷遠離零的近似方式。

那 banker rounding 呢?我們用上面存錢的例子測試:

saved = round(1.5) + round(2.5) + round(3.5) + round(4.5)
print(saved, saved / 4)
12 3.0

這才接近真正存入的錢!banker rounding 解決了普通四捨五入讓數字不斷膨脹的問題。

好了,我們明天見!

參考:Python 3: Deep Dive (Part 1 - Functional)


上一篇
Python 與浮點數(float):簡化浮點數
下一篇
Python 與十進位——使用 Decimals
系列文
小青蛇變大蟒蛇——進階Python學起來!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
alexvan
iT邦新手 5 級 ‧ 2022-10-16 16:27:44

bankers' rounding, banker's rounding, 或bankers rounding,不是banker rounding

我要留言

立即登入留言